using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;
using Lidgren.Network;

namespace MvdDonk.Bomberman.Lib
{
    public class MovementMessage : IMessage
    {
        public char Action { get { return 'M'; } }
        public long NetworkId { get; set; }
        public Vector2 MovementVector { get; private set; }
        public EntityMovementState MovementState { get; private set; }

        public MovementMessage(Vector2 movementVector, EntityMovementState movementState)
        {
            MovementState = movementState;
            MovementVector = movementVector;
        }

        public MovementMessage(Vector2 movementVector, EntityMovementState movementState, long networkId)
        {
            MovementState = movementState;
            MovementVector = movementVector;
            NetworkId = networkId;
        }

        public void SendToServer(NetClient client)
        {
            var msg = client.CreateMessage();
            msg.Write(Action);
            msg.Write(CreateMovementState(MovementState));
            msg.Write(MovementVector.X);
            msg.Write(MovementVector.Y);
            client.SendMessage(msg, NetDeliveryMethod.ReliableSequenced);
        }

        public void SendToClient(NetServer server, NetConnection recipient)
        {
            var msg = server.CreateMessage();
            msg.Write(Action);
            msg.Write(NetworkId);
            msg.Write(CreateMovementState(MovementState));
            msg.Write(MovementVector.X);
            msg.Write(MovementVector.Y);
            server.SendMessage(msg, recipient, NetDeliveryMethod.ReliableSequenced);
        }

        public static char CreateMovementState(EntityMovementState state)
        {
            switch (state)
            {
                case EntityMovementState.WalkingDown: return 'D';
                case EntityMovementState.WalkingUp: return 'U';
                case EntityMovementState.WalkingLeft: return 'L';
                case EntityMovementState.WalkingRight: return 'R';
                default: return 'I';
            }
        }

        public static EntityMovementState GetMovementState(char state)
        {
            switch (state)
            {
                case 'D': return EntityMovementState.WalkingDown;
                case 'U': return EntityMovementState.WalkingUp;
                case 'L': return EntityMovementState.WalkingLeft;
                case 'R': return EntityMovementState.WalkingRight;
                default: return EntityMovementState.Idle;
            }
        }

        public static MovementMessage ReceiveFromServer(NetIncomingMessage msg)
        {
            var networkId = msg.ReadInt64();
            var movementState = (char)msg.ReadBytes(2)[0];
            var x = msg.ReadFloat();
            var y = msg.ReadFloat();

            var message = new MovementMessage(new Vector2(x, y), GetMovementState(movementState));
            message.NetworkId = networkId;
            return message;
        }

        public static MovementMessage ReceiveFromClient(NetIncomingMessage msg)
        {
            var networkId = msg.SenderConnection.RemoteUniqueIdentifier;
            var movementState = (char)msg.ReadBytes(2)[0];
            var x = msg.ReadFloat();
            var y = msg.ReadFloat();

            var message = new MovementMessage(new Vector2(x, y), GetMovementState(movementState));
            message.NetworkId = networkId;
            return message;
        }
    }
}
